package com.uh.rds.tester.console;


import com.uh.rds.testing.config.TestConfigManager;
import com.uh.console.client.ConsoleWebClient;
import com.uh.console.client.RdsJedisClientActions;
import org.junit.jupiter.api.*;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class DataMaintenanceTest {
    private ConsoleWebClient client;
    private RdsJedisClientActions actions;

    private AtomicInteger count = new AtomicInteger(0);

    @BeforeAll
    public void init() {
        client = ConsoleWebClient.getInstance(TestConfigManager.getConsoleClientConf());
        client.login();

        actions = new RdsJedisClientActions(client);
    }


    @Test
    @Order(0)
    public void TestClient() throws Exception {

        List<Integer> numbers = new ArrayList<>();
        numbers.add(10);
        numbers.add(20);
//        numbers.add(30);
//        numbers.add(40);
//        numbers.add(50);
//        numbers.add(60);
//        numbers.add(70);

        for (Integer number : numbers) {
            startReq(number, 12);
        }
        Assertions.assertEquals(count.get(), 0);

    }


    private void startReq(int number, long serviceId) throws Exception {
        ArrayList<Long> thread1List = new ArrayList<>();
        ArrayList<Long> thread2List = new ArrayList<>();

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < number; i++) {
                thread1List.addAll(start(serviceId));
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < number; i++) {
                thread2List.addAll(start(serviceId));
            }
        });
        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();

        long sumT1 = 0;
        for (Long t1 : thread1List) {
            sumT1 += t1;
        }

        long sumT2 = 0;
        for (Long t1 : thread2List) {
            sumT2 += t1;
        }

        System.out.println("===============================================");
        String s = "thread%d 请求：%d次 平均延迟：%.2f";
        System.out.printf((s) + "%n", 1, number, (sumT1 * 1.0) / thread1List.size());
        System.out.println("thread1 最大延迟：" + thread1List.stream().max(Long::compare).orElse(null));
        System.out.printf((s) + "%n", 2, number, (sumT2 * 1.0) / thread2List.size());
        System.out.println("thread2 最大延迟：" + thread2List.stream().max(Long::compare).orElse(null));
        System.out.println("===============================================");
        System.out.println();
    }

    private List<Long> start(long serviceId) {
        List<Long> longs = new ArrayList<>();

        long start = System.currentTimeMillis();
        String dbRes = actions.getDb(serviceId);
        if (dbRes != null) {
            System.out.println(dbRes);
            count.incrementAndGet();
        }
        long end = System.currentTimeMillis();
        longs.add(end - start);

        start = System.currentTimeMillis();
        String keyRes = actions.getKey(serviceId, "ZGZhZmRh", 0);
        if (keyRes != null) {
            System.out.println(keyRes);
            count.incrementAndGet();
        }
        end = System.currentTimeMillis();
        longs.add(end - start);

        start = System.currentTimeMillis();
        String keyListRes = actions.keyList(serviceId, 0);
        if (keyListRes != null) {
            System.out.println(keyListRes);
            count.incrementAndGet();
        }
        end = System.currentTimeMillis();
        longs.add(end - start);

        start = System.currentTimeMillis();
        String keyTypeRes = actions.keyType(14, 0, "a2V5OjAwMDA4MTc1MTk0MA==");
        if (keyTypeRes != null) {
            System.out.println(keyTypeRes);
            count.incrementAndGet();
        }
        end = System.currentTimeMillis();
        longs.add(end - start);


        return longs;

    }
}
